{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.model_selection import train_test_split\n",
    "import _pickle as cPickle\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>play_count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOCKSGZ12A58A7CA4B</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOCVTLJ12A6310F0FD</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SODLLYS12A8C13A96B</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOEGIYH12A6D4FC0E3</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOFRQTD12A81C233C0</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                       user                song  play_count\n",
       "0  4e11f45d732f4861772b2906f81a7d384552ad12  SOCKSGZ12A58A7CA4B           1\n",
       "1  4e11f45d732f4861772b2906f81a7d384552ad12  SOCVTLJ12A6310F0FD           1\n",
       "2  4e11f45d732f4861772b2906f81a7d384552ad12  SODLLYS12A8C13A96B           3\n",
       "3  4e11f45d732f4861772b2906f81a7d384552ad12  SOEGIYH12A6D4FC0E3           1\n",
       "4  4e11f45d732f4861772b2906f81a7d384552ad12  SOFRQTD12A81C233C0           2"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dpath = 'music/Data/'\n",
    "data = pd.read_csv(dpath+'triplet_dataset_sub.csv')\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 37519 entries, 0 to 37518\n",
      "Data columns (total 3 columns):\n",
      "user          37519 non-null object\n",
      "song          37519 non-null object\n",
      "play_count    37519 non-null int64\n",
      "dtypes: int64(1), object(2)\n",
      "memory usage: 879.5+ KB\n"
     ]
    }
   ],
   "source": [
    "data.info()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>play_count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>count</td>\n",
       "      <td>37519.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>mean</td>\n",
       "      <td>8.799222</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>std</td>\n",
       "      <td>33.401146</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>min</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>25%</td>\n",
       "      <td>1.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>50%</td>\n",
       "      <td>3.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>75%</td>\n",
       "      <td>8.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>max</td>\n",
       "      <td>3532.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         play_count\n",
       "count  37519.000000\n",
       "mean       8.799222\n",
       "std       33.401146\n",
       "min        1.000000\n",
       "25%        1.000000\n",
       "50%        3.000000\n",
       "75%        8.000000\n",
       "max     3532.000000"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data.describe()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "800"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(data['song'].unique())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "790"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(data['user'].unique())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>play_count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>37183</td>\n",
       "      <td>1db9458849024e54f89a807790230aa5701f112d</td>\n",
       "      <td>SOHJOLH12A6310DFE5</td>\n",
       "      <td>15</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>37184</td>\n",
       "      <td>1db9458849024e54f89a807790230aa5701f112d</td>\n",
       "      <td>SOHTKMO12AB01843B0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>37185</td>\n",
       "      <td>1db9458849024e54f89a807790230aa5701f112d</td>\n",
       "      <td>SOITRTA12A6D4F8261</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>37186</td>\n",
       "      <td>1db9458849024e54f89a807790230aa5701f112d</td>\n",
       "      <td>SOTMKZF12AB0187412</td>\n",
       "      <td>16</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>37187</td>\n",
       "      <td>1db9458849024e54f89a807790230aa5701f112d</td>\n",
       "      <td>SOTVFIU12AC46878B7</td>\n",
       "      <td>17</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                           user                song  \\\n",
       "37183  1db9458849024e54f89a807790230aa5701f112d  SOHJOLH12A6310DFE5   \n",
       "37184  1db9458849024e54f89a807790230aa5701f112d  SOHTKMO12AB01843B0   \n",
       "37185  1db9458849024e54f89a807790230aa5701f112d  SOITRTA12A6D4F8261   \n",
       "37186  1db9458849024e54f89a807790230aa5701f112d  SOTMKZF12AB0187412   \n",
       "37187  1db9458849024e54f89a807790230aa5701f112d  SOTVFIU12AC46878B7   \n",
       "\n",
       "       play_count  \n",
       "37183          15  \n",
       "37184           1  \n",
       "37185           1  \n",
       "37186          16  \n",
       "37187          17  "
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test = data[data['user'] == '1db9458849024e54f89a807790230aa5701f112d']\n",
    "test.head()"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "# 打分规则 播放次数最多的为100分，播放至少大于5次， 比例差不多的按100 乘以比例计算其他的分数\n",
    "# 分数越高代表播放次数越多"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>play_count</th>\n",
       "      <th>score</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOCKSGZ12A58A7CA4B</td>\n",
       "      <td>1</td>\n",
       "      <td>12.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOCVTLJ12A6310F0FD</td>\n",
       "      <td>1</td>\n",
       "      <td>12.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SODLLYS12A8C13A96B</td>\n",
       "      <td>3</td>\n",
       "      <td>37.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOEGIYH12A6D4FC0E3</td>\n",
       "      <td>1</td>\n",
       "      <td>12.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOFRQTD12A81C233C0</td>\n",
       "      <td>2</td>\n",
       "      <td>25.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                       user                song  play_count  \\\n",
       "0  4e11f45d732f4861772b2906f81a7d384552ad12  SOCKSGZ12A58A7CA4B           1   \n",
       "1  4e11f45d732f4861772b2906f81a7d384552ad12  SOCVTLJ12A6310F0FD           1   \n",
       "2  4e11f45d732f4861772b2906f81a7d384552ad12  SODLLYS12A8C13A96B           3   \n",
       "3  4e11f45d732f4861772b2906f81a7d384552ad12  SOEGIYH12A6D4FC0E3           1   \n",
       "4  4e11f45d732f4861772b2906f81a7d384552ad12  SOFRQTD12A81C233C0           2   \n",
       "\n",
       "   score  \n",
       "0   12.5  \n",
       "1   12.5  \n",
       "2   37.5  \n",
       "3   12.5  \n",
       "4   25.0  "
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "min_song_num = 5\n",
    "max_scores = 100.0\n",
    "temp_data = data.copy()\n",
    "temp_data['score'] = 10\n",
    "user_list = list(temp_data[temp_data['play_count']>min_song_num]['user'].unique())\n",
    "for user in user_list:\n",
    "    temp_user = temp_data[temp_data['user']==user]\n",
    "    max_nu = temp_user['play_count'].max()\n",
    "    pre_i = max_scores / max_nu\n",
    "    for index in list(temp_data[temp_data['user']==user].index):\n",
    "        temp_data.loc[index,'score'] = int(temp_data.iloc[index]['play_count']) * pre_i\n",
    "    \n",
    "temp_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>score</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>0</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOCKSGZ12A58A7CA4B</td>\n",
       "      <td>12.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>1</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOCVTLJ12A6310F0FD</td>\n",
       "      <td>12.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>2</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SODLLYS12A8C13A96B</td>\n",
       "      <td>37.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>3</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOEGIYH12A6D4FC0E3</td>\n",
       "      <td>12.5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>4</td>\n",
       "      <td>4e11f45d732f4861772b2906f81a7d384552ad12</td>\n",
       "      <td>SOFRQTD12A81C233C0</td>\n",
       "      <td>25.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                       user                song  score\n",
       "0  4e11f45d732f4861772b2906f81a7d384552ad12  SOCKSGZ12A58A7CA4B   12.5\n",
       "1  4e11f45d732f4861772b2906f81a7d384552ad12  SOCVTLJ12A6310F0FD   12.5\n",
       "2  4e11f45d732f4861772b2906f81a7d384552ad12  SODLLYS12A8C13A96B   37.5\n",
       "3  4e11f45d732f4861772b2906f81a7d384552ad12  SOEGIYH12A6D4FC0E3   12.5\n",
       "4  4e11f45d732f4861772b2906f81a7d384552ad12  SOFRQTD12A81C233C0   25.0"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res_data = temp_data.drop(['play_count'],axis=1)\n",
    "res_data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(37519, 3)"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "res_data.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 字典用于建立用户和物品索引\n",
    "from collections import defaultdict\n",
    "\n",
    "# 稀疏矩阵\n",
    "import scipy.io as sio\n",
    "import scipy.sparse as ss\n",
    "\n",
    "# 数据文件存储\n",
    "import _pickle as cPickle"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_train,x_test,y_train,y_test = train_test_split(data[['user','song']],res_data['score'],test_size=0.2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>score</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>18707</td>\n",
       "      <td>b4cfdefb94d1df6714c9962923edb73470e6fa7b</td>\n",
       "      <td>SOFCPOU12A8C13BF40</td>\n",
       "      <td>24.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>5704</td>\n",
       "      <td>4bcc4cfd9acf7e19bbccd398f8503ba79fb66513</td>\n",
       "      <td>SOWCKVR12A8C142411</td>\n",
       "      <td>20.714286</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>27517</td>\n",
       "      <td>42ac141a65053a2ba02c5380ccf7975022e307a6</td>\n",
       "      <td>SOWOMMY127F8096DF9</td>\n",
       "      <td>56.521739</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>14695</td>\n",
       "      <td>625d0167edbc5df88e9fbebe3fcdd6b121a316bb</td>\n",
       "      <td>SOPKPFW12A6D4F84BC</td>\n",
       "      <td>3.448276</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>33435</td>\n",
       "      <td>22f6aae94643c2cea285413068f80274e7f1f75e</td>\n",
       "      <td>SONHWUN12AC468C014</td>\n",
       "      <td>29.729730</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                           user                song      score\n",
       "18707  b4cfdefb94d1df6714c9962923edb73470e6fa7b  SOFCPOU12A8C13BF40  24.000000\n",
       "5704   4bcc4cfd9acf7e19bbccd398f8503ba79fb66513  SOWCKVR12A8C142411  20.714286\n",
       "27517  42ac141a65053a2ba02c5380ccf7975022e307a6  SOWOMMY127F8096DF9  56.521739\n",
       "14695  625d0167edbc5df88e9fbebe3fcdd6b121a316bb  SOPKPFW12A6D4F84BC   3.448276\n",
       "33435  22f6aae94643c2cea285413068f80274e7f1f75e  SONHWUN12AC468C014  29.729730"
      ]
     },
     "execution_count": 70,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train = pd.concat([x_train,y_train],axis=1)\n",
    "train.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>score</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <td>30628</td>\n",
       "      <td>b7c24f770be6b802805ac0e2106624a517643c17</td>\n",
       "      <td>SOEBOWM12AB017F279</td>\n",
       "      <td>10.810811</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>31485</td>\n",
       "      <td>9254a3fdc569428c3b1c3904db36d485c47e2544</td>\n",
       "      <td>SOPXKYD12A6D4FA876</td>\n",
       "      <td>23.076923</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>16920</td>\n",
       "      <td>31aad1036a404737ee8b88ea2da68813c9a46874</td>\n",
       "      <td>SOQJHUW12AB0188A24</td>\n",
       "      <td>2.678571</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>16954</td>\n",
       "      <td>e3e8103d0751e29693f9b03a58efa5c21acf2115</td>\n",
       "      <td>SODJWHY12A8C142CCE</td>\n",
       "      <td>17.241379</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <td>25098</td>\n",
       "      <td>520bb6f7bd2fc51d02f236398acdc5170cc299a8</td>\n",
       "      <td>SOWNVIV12AB0184846</td>\n",
       "      <td>12.500000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                           user                song      score\n",
       "30628  b7c24f770be6b802805ac0e2106624a517643c17  SOEBOWM12AB017F279  10.810811\n",
       "31485  9254a3fdc569428c3b1c3904db36d485c47e2544  SOPXKYD12A6D4FA876  23.076923\n",
       "16920  31aad1036a404737ee8b88ea2da68813c9a46874  SOQJHUW12AB0188A24   2.678571\n",
       "16954  e3e8103d0751e29693f9b03a58efa5c21acf2115  SODJWHY12A8C142CCE  17.241379\n",
       "25098  520bb6f7bd2fc51d02f236398acdc5170cc299a8  SOWNVIV12AB0184846  12.500000"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test = pd.concat([x_test,y_test],axis=1)\n",
    "test.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [],
   "source": [
    "train.to_csv(dpath+'train.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [],
   "source": [
    "test.to_csv(dpath+'test.csv')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "user num: 784 items num: 800\n"
     ]
    }
   ],
   "source": [
    "users_unique = train['user'].unique()\n",
    "n_users = users_unique.shape[0]\n",
    "items_unique = train['song'].unique()\n",
    "n_items = items_unique.shape[0]\n",
    "print('user num: {} items num: {}'.format(n_users,n_items))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 建立用户和物品索引\n",
    "users_index = dict()\n",
    "items_index = dict()\n",
    "for j,u in enumerate(users_unique):\n",
    "    users_index[u] = j\n",
    "for j,i in enumerate(items_unique):\n",
    "    items_index[i] = j\n",
    "cPickle.dump(users_index,open(dpath+'users_index.pkl','wb'))\n",
    "cPickle.dump(items_index,open(dpath+'items_index.pkl','wb'))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [],
   "source": [
    "train = train.reset_index(drop=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ok\n"
     ]
    }
   ],
   "source": [
    "# 倒排序\n",
    "# 统计用户打过分的电影  / 每个电影被哪些用户打过分\n",
    "user_items = defaultdict(set)\n",
    "item_users = defaultdict(set)\n",
    "\n",
    "# 用户-物品关系矩阵R， 稀疏矩阵，记录用户对每个电影的打分\n",
    "user_item_scores = ss.dok_matrix((n_users,n_items))\n",
    "\n",
    "# 扫描训练数据\n",
    "for line in train.index:\n",
    "    cur_user_index = users_index[train.iloc[line]['user']]\n",
    "    cur_item_index = items_index[train.iloc[line]['song']]\n",
    "    \n",
    "    #倒排表\n",
    "    user_items[cur_user_index].add(cur_item_index)  # 该用户对这个电影打了分\n",
    "    item_users[cur_item_index].add(cur_user_index)  # 这个电影被该用户打分\n",
    "    user_item_scores[cur_user_index,cur_item_index] = train.iloc[line]['score'] # 用户和电影间的分数\n",
    "    \n",
    "# 保存倒排序表\n",
    "cPickle.dump(user_items , open(dpath+'user_items.pkl','wb'))\n",
    "cPickle.dump(item_users,open(dpath+'item_users.pkl','wb'))\n",
    "\n",
    "# 保存打分矩阵\n",
    "cPickle.dump(user_item_scores,open(dpath+'user_item_scores.pkl','wb'))\n",
    "\n",
    "print('ok')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [],
   "source": [
    "sio.mmwrite(dpath+'user_item_scores',user_item_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
